home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 7 / Night Owl Shareware (NOPV7)(Night Owl Publisher Inc.)(1992).bin / 038a / bash1_12.arj / BASH1-12.TAR / bash-1.12 / builtins / kill.def < prev    next >
Text File  |  1991-12-30  |  6KB  |  263 lines

  1. This file is kill.def, from which is created kill.c.
  2. It implements the builtin "kill" in Bash.
  3.  
  4. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
  5.  
  6. This file is part of GNU Bash, the Bourne Again SHell.
  7.  
  8. Bash is free software; you can redistribute it and/or modify it under
  9. the terms of the GNU General Public License as published by the Free
  10. Software Foundation; either version 1, or (at your option) any later
  11. version.
  12.  
  13. Bash is distributed in the hope that it will be useful, but WITHOUT ANY
  14. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16. for more details.
  17.  
  18. You should have received a copy of the GNU General Public License along
  19. with Bash; see the file COPYING.  If not, write to the Free Software
  20. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  
  22. $PRODUCES kill.c
  23.  
  24. $BUILTIN kill
  25. $FUNCTION kill_builtin
  26. $DEPENDS_ON JOB_CONTROL
  27. $SHORT_DOC kill [-s sigspec | -sigspec] [pid | job]... | -l [signum]
  28. Send the processes named by PID (or JOB) the signal SIGSPEC.  If
  29. SIGSPEC is not present, then SIGTERM is assumed.  An argument of `-l'
  30. lists the signal names; if arguments follow `-l' they are assumed to
  31. be signal numbers for which names should be listed.  Kill is a builtin
  32. for two reasons: it allows job ID's to be used instead of pids, and if
  33. you run out of processes, you can still kill them.
  34. $END
  35.  
  36. #include <sys/types.h>
  37. #include <errno.h>
  38. extern int errno;
  39.  
  40. #include "../shell.h"
  41. #include "../trap.h"
  42. #include "../jobs.h"
  43.  
  44. #if defined (JOB_CONTROL)
  45. extern int job_control;
  46.  
  47. #if !defined (CONTINUE_AFTER_KILL_ERROR)
  48. #  define CONTINUE_OR_FAIL return (EXECUTION_FAILURE)
  49. #else
  50. #  define CONTINUE_OR_FAIL goto continue_killing
  51. #endif /* CONTINUE_AFTER_KILL_ERROR */
  52.  
  53. /* Here is the kill builtin.  We only have it so that people can type
  54.    kill -KILL %1?  No, if you fill up the process table this way you
  55.    can still kill some. */
  56. int
  57. kill_builtin (list)
  58.      WORD_LIST *list;
  59. {
  60.   int signal = SIGTERM;
  61.   int any_succeeded = 0, listing = 0, saw_signal = 0;
  62.   char *sigspec;
  63.   pid_t pid;
  64.  
  65.   if (!list)
  66.     return (EXECUTION_SUCCESS);
  67.  
  68.   /* Process options. */
  69.   while (list)
  70.     {
  71.       if (strcmp (list->word->word, "-l") == 0)
  72.     {
  73.       listing++;
  74.       list = list->next;
  75.     }
  76.       else if (strcmp (list->word->word, "-s") == 0)
  77.     {
  78.       list = list->next;
  79.       if (list)
  80.         {
  81.           sigspec = list->word->word;
  82.           if (strcmp (sigspec, "0") == 0)
  83.         signal = 0;
  84.           else
  85.         signal = decode_signal (sigspec);
  86.           list = list->next;
  87.         }
  88.       else
  89.         {
  90.           builtin_error ("-s requires an argument");
  91.           return (EXECUTION_FAILURE);
  92.         }
  93.     }
  94.       else if (strcmp (list->word->word, "--") == 0)
  95.     {
  96.       list = list->next;
  97.       break;
  98.     }
  99.       /* If this is a signal specification then process it.  We only process
  100.      the first one seen; other arguments may signify process groups (e.g,
  101.      -num == process group num). */
  102.       else if ((*(list->word->word) == '-') && !saw_signal)
  103.     {
  104.       sigspec = &(list->word->word)[1];
  105.       signal = decode_signal (sigspec);
  106.       saw_signal++;
  107.       list = list->next;
  108.     }
  109.       else
  110.     break;
  111.     }
  112.  
  113.   if (listing)
  114.     {
  115.       if (!list)
  116.     {
  117.       register int i, column = 0;
  118.       for (i = 1; i < NSIG; i++)
  119.         {
  120.           char *name = signal_name (i);
  121.           if ((strncmp (name, "SIGJUNK", 7) == 0) ||
  122.           (strncmp (name, "Unknown", 7) == 0))
  123.         continue;
  124.  
  125.           printf ("%2d) %s", i, name);
  126.  
  127.           if (++column < 4)
  128.         printf ("\t");
  129.           else
  130.         {
  131.           printf ("\n");
  132.           column = 0;
  133.         }
  134.         }
  135.  
  136.       if (column != 0)
  137.         printf ("\n");
  138.     }
  139.       else
  140.     {
  141.       /* List individual signal names. */
  142.       while (list)
  143.         {
  144.           int signum;
  145.           char *name;
  146.  
  147.           if ((sscanf (list->word->word, "%d", &signum) != 1) ||
  148.           (signum <= 0))
  149.         {
  150.         list_error:
  151.           builtin_error ("bad signal number: %s", list->word->word);
  152.           list = list->next;
  153.           continue;
  154.         }
  155.  
  156.           /* This is specified by Posix.2 so that exit statuses can be
  157.          mapped into signal numbers. */
  158.           if (signum > 128)
  159.         signum -= 128;
  160.  
  161.           if (signum > NSIG)
  162.         goto list_error;
  163.  
  164.           name = signal_name (signum);
  165.           if ((strncmp (name, "SIGJUNK", 7) == 0) ||
  166.           (strncmp (name, "Unknown", 7) == 0))
  167.         {
  168.           list = list->next;
  169.           continue;
  170.         }
  171.           printf ("%s\n", name);
  172.           list = list->next;
  173.         }
  174.     }
  175.       return (EXECUTION_SUCCESS);
  176.     }
  177.  
  178.   /* OK, we are killing processes. */
  179.   if (signal == NO_SIG)
  180.     {
  181.       builtin_error ("bad signal spec `%s'", sigspec);
  182.       return (EXECUTION_FAILURE);
  183.     }
  184.  
  185.   while (list)
  186.     {
  187.       char *word = list->word->word;
  188.  
  189.       if (*word == '-')
  190.     word++;
  191.  
  192.       if (all_digits (word))
  193.     {
  194.       /* Use the entire argument in case of minus sign presence. */
  195.       pid = (pid_t) atoi (list->word->word);
  196.  
  197.       if (kill_pid (pid, signal, 0) < 0)
  198.         goto signal_error;
  199.       else
  200.         any_succeeded++;
  201.     }
  202.       else if (*list->word->word != '%')
  203.     {
  204.       builtin_error ("No such pid %s", list->word->word);
  205.       CONTINUE_OR_FAIL;
  206.     }
  207.       else if (job_control)    /* can't kill jobs if not using job control */
  208.     {            /* Must be a job spec.  Check it out. */
  209.       int job;
  210.       sigset_t set, oset;
  211.  
  212.       BLOCK_CHILD (set, oset);
  213.       job = get_job_spec (list);
  214.  
  215.       if (job < 0 || job >= job_slots || !jobs[job])
  216.         {
  217.           if (job != DUP_JOB)
  218.         builtin_error ("No such job %s", list->word->word);
  219.           UNBLOCK_CHILD (oset);
  220.           CONTINUE_OR_FAIL;
  221.         }
  222.  
  223.       /* Job spec used.  Kill the process group. If the job was started
  224.          without job control, then its pgrp == shell_pgrp, so we have
  225.          to be careful.  We take the pid of the first job in the pipeline
  226.          in that case. */
  227.       if (jobs[job]->job_control)
  228.         pid = jobs[job]->pgrp;
  229.       else
  230.         pid = jobs[job]->pipe->pid;
  231.  
  232.       UNBLOCK_CHILD (oset);
  233.  
  234.       if (kill_pid (pid, signal, 1) < 0)
  235.         {
  236.         signal_error:
  237.           if (errno == EPERM)
  238.         builtin_error ("(%d) - Not owner", (int)pid);
  239.           else if (errno == ESRCH)
  240.         builtin_error ("(%d) - No such pid", (int)pid);
  241.           else
  242.         builtin_error ("Invalid signal %d", signal);
  243.           CONTINUE_OR_FAIL;
  244.         }
  245.       else
  246.         any_succeeded++;
  247.     }
  248.       else
  249.     {
  250.       builtin_error ("bad process specification `%s'", list->word->word);
  251.       CONTINUE_OR_FAIL;
  252.     }
  253.     continue_killing:
  254.       list = list->next;
  255.     }
  256.  
  257.   if (any_succeeded)
  258.     return (EXECUTION_SUCCESS);
  259.   else
  260.     return (EXECUTION_FAILURE);
  261. }
  262. #endif /* JOB_CONTROL */
  263.